﻿using ProtoBuf;
using System.Net;

namespace SyncDemo.Sync.Models
{
    [ProtoContract(Name = nameof(AddressPortInfo))]
    public class AddressPortInfo
    {
        #region props

        [ProtoMember(1)]
        public string Address { get; set; }

        [ProtoMember(2)]
        public int Port { get; set; }

        #endregion

        #region ctors
        public AddressPortInfo()
        {

        }

        public AddressPortInfo(IPEndPoint ep)
        {
            if (ep == null) return;
            Address = ep.Address.ToString();
            Port = ep.Port;
        }

        public AddressPortInfo(EndPoint ep) : this(ep as IPEndPoint)
        {

        }

        #endregion


        #region equal
        public override int GetHashCode()
        {
            return Address.GetHashCode() + Port.GetHashCode();
        }

        public override bool Equals(object? obj)
        {
            if (obj is null) return false;
            if (GetHashCode() != obj.GetHashCode()) return false;
            if (obj is AddressPortInfo other)
            {
                if (Address != other.Address) return true;
                if (Port != other.Port) return true;
                return true;
            }
            return false;
        }

        public static bool operator ==(AddressPortInfo a, AddressPortInfo b)
        {
            if (a is null && b is null) return true;
            if (a is null == false) return a.Equals(b);
            return false;
        }

        public static bool operator !=(AddressPortInfo a, AddressPortInfo b)
        {
            return !(a == b);
        }
        #endregion


        #region convert
        public IPEndPoint ToIPEndPoint()
        {
            return new IPEndPoint(IPAddress.Parse(Address), Port);
        }

        #endregion

        #region overrides
        public override string ToString()
        {
            return $"{Address}:{Port}";
        }
        #endregion

        #region statics

        public static bool TryParse(string text, out AddressPortInfo info)
        {
            info = default;

            if (string.IsNullOrWhiteSpace(text)) return false;
            var split = text.Split(':');
            if (split.Length != 2) return false;
            var ipAddress = split[0];
            var port = split[1];
            var portNumber = int.Parse(port);

            info = new AddressPortInfo() { Address = ipAddress, Port = portNumber };

            return true;
        }

        #endregion
    }
}
